
#include "ListaEnlazada.h"

ListaEnlazada::ListaEnlazada(string nombre) {
	string arch(nombre+"."+ARCH_LISTAENLAZADA_EXT);
	//intento abrir el archivo
	this->flujo.open(arch.c_str(), ios_base::in|ios_base::out|ios_base::binary);
	//si hay error es porque no existe y lo creo
	if ((!this->flujo)||(!this->flujo.good())||(this->flujo.bad())){
		this->flujo.open(arch.c_str(), ios_base::in|ios_base::out|ios_base::binary|ios_base::trunc);

		short tamCampo=sizeof(short);
		short numero=0;

		//sig bloque + numero de bloques libres + bloques libres
		this->flujo.seekp(0);//me paro en la posicion 0
		this->flujo.write((char*)&numero,tamCampo);//guardo el numero de bloque sig

		this->flujo.seekp(tamCampo);//me paro en la posicion tamCampo
		this->flujo.write((char*)&numero,tamCampo);//guardo el numero de bloques liberados
	}
}

/* --------------------------------------------------------------------------------------------------------------- */
/* PRE:  Instancia creada
   POST: destruye la instancia */
ListaEnlazada::~ListaEnlazada() {
	if (this->flujo)
		this->flujo.close();
}

/* --------------------------------------------------------------------------------------------------------------- */
/* PRE:  Instancia creada
   POST: Devuelve un numero de bloque libre, primero se fija en la pila si ya hay alguno libre para ser
         reutilizado caso contrario retorna -1*/
short ListaEnlazada::pedirBloqueLibre(){

	short cantBlqLibres=0;
	short tamCampo=sizeof(short);
	short blq=0;

	this->flujo.seekg(tamCampo);
	this->flujo.read((char*)&cantBlqLibres, tamCampo); //leo cantidad de bloques liberados


	if (cantBlqLibres > 0){//si hay bloques liberados tomo el ultimo, funciona como una pila
		this->flujo.seekg(tamCampo*cantBlqLibres + tamCampo);
		this->flujo.read((char*)&blq, tamCampo);
		//descuento en 1 la cantidad de bloques libres
		cantBlqLibres--;
		this->flujo.seekg(tamCampo);
		this->flujo.write((char*)&cantBlqLibres,tamCampo);//guardo el numero de bloques liberados
		return(blq);
	}
	else{ //si no hay bloques libres, devuelvo el sig al ultimo generado
		return -1;

	}
}

/* --------------------------------------------------------------------------------------------------------------- */
/* PRE:  Instancia creada y el numero de bloque no esta en la instancia
   POST: Agrega el numero de bloque libre para luego ser reutilizado */
void ListaEnlazada::agregarBloqueLibre(short blq){
	short cantBlqLibres;
	short tamCampo=sizeof(short);

	this->flujo.seekg(tamCampo);
	this->flujo.read((char*)&cantBlqLibres, tamCampo);

	//aumento en 1 la cantidad de bloques libres;
	cantBlqLibres++;
	this->flujo.seekg(tamCampo);
	this->flujo.write((char*)&cantBlqLibres,tamCampo);//guardo el numero de bloques liberados

	//guardo el numero de bloque liberado
	this->flujo.seekg(tamCampo*cantBlqLibres + tamCampo);
	this->flujo.write((char*)&blq, tamCampo);//inserto el numero de bloque liberadom funciona como una pila

}
